import { hsv2hsl, rgb2hsv, hsv2rgb, rgbtoHex, hsl2hsv, parseRgbaColor } from './converted.js'
import { initgradinet, genId } from './REG_gradients.js'
const res = initgradinet();
export default class Color {
    constructor(options) {
        this.enableAlpha = false;//是否显示透明度
        this.format = 'rgb';//默认输出格式
        this.gradientDots = 2;//渐变色的点

        this._hue = 0;//色相 是色轮上从 0 到 360 的度数。0 是红色，120 是绿色，240 是蓝色
        this._saturation = 100; //饱和度
        this._value = 100;//明亮

        this.colorValue = '';//单色得到的颜色值
        this._alpha = 100; //透明度

        //  渐变色思路  首先应该要有开始颜色和结束颜色这是必须的 对应页面上必须要有两个滑块 点击滑轨时也可以添加滑块 将渐变色抽象成一个数组
        //  数组中每个元素都要包含颜色 占比 和标识拖动滑块时改变这个颜色的占比
        this._gradientcolor = false;//当前是否渐变
        this._angle = 90;//默认角度
        this._genGradientPoint = [];//当前渐变色数组
        this._genGradientPoint = res.colorStopList.map((item) => ({ color: item.color, position: item.position, 'genid': genId() }));
        this._angle = res.angle.replace(/deg/g, "");//默认角度
        this.currentgenid = this._genGradientPoint[0].genid
        this._lineMove = this._genGradientPoint[0].position;
        this.gradientcolorValue = ""


        options = options || {};
        // 覆盖默认属性
        for (let option in options) {
            if (Object.prototype.hasOwnProperty.call(options, option)) {
                this[option] = options[option];
            }
        }
        this.doOnChange()
    }



    init(color) {
        this._hue = 0;//色相 是色轮上从 0 到 360 的度数。0 是红色，120 是绿色，240 是蓝色
        this._saturation = 100; //饱和度
        this._value = 100;//明亮

        this.colorValue = '';//单色得到的颜色值
        this._alpha = 100; //透明度

        //  渐变色思路  首先应该要有开始颜色和结束颜色这是必须的 对应页面上必须要有两个滑块 点击滑轨时也可以添加滑块 将渐变色抽象成一个数组
        //  数组中每个元素都要包含颜色 占比 和标识拖动滑块时改变这个颜色的占比
        this._gradientcolor = false;//当前是否渐变
        this._angle = 90;//默认角度
        this._genGradientPoint = [];//当前渐变色数组
        this._genGradientPoint = res.colorStopList.map((item) => ({ color: item.color, position: item.position, 'genid': genId() }));
        this._angle = res.angle.replace(/deg/g, "");//默认角度
        this.currentgenid = this._genGradientPoint[0].genid
        this._lineMove = this._genGradientPoint[0].position;
        this.gradientcolorValue = ""
        this.doOnChange();
        if (color) {
            this.haveColor(color)
        }
    }

    haveColor(color) {
        let result, rGradientEnclosedInBrackets = /.*gradient\s*\(((?:\([^\)]*\)|[^\)\(]*)*)\)/;
        rGradientEnclosedInBrackets.lastIndex = 0;
        result = rGradientEnclosedInBrackets.exec(color);
        this._gradientcolor = !result ? false : true
        if (this._gradientcolor) {
            this.gradientcolorValue = color;
            const colorRes = initgradinet(color);
            this._genGradientPoint = colorRes.colorStopList.map((item) => ({ color: item.color, position: item.position, 'genid': genId() }));
            this._angle = colorRes.angle.replace(/deg/g, "");//默认角度
            this.currentgenidChang(this._genGradientPoint[0].genid)
        } else {
            this.colorValue = color;//单色得到的颜色值
            this.setcurrentHSVA()
            this.doOnChange();

        }
    }

    set(prop, value) {
        if (arguments.length === 1 && typeof prop === 'object') {
            for (let p in prop) {
                if (Object.prototype.hasOwnProperty.call(prop, p)) {
                    this.set(p, prop[p]);
                }
            }
            return;
        }
        this['_' + prop] = value;
        this.doOnChange();
        //判断是否加载渐变色
        if (this._gradientcolor) {
            //单色改变设置渐变色的某一个点的颜色
            this.doChangeLineposition()
        } else {

        }
    }

    get(prop) {
        return this['_' + prop]
    }

    doOnChange() {
        const { _hue, _saturation, _value, _alpha, format } = this;
        if (this.enableAlpha) {
            //支持透明度
            switch (format) {
                case 'hsl': {
                    const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100);
                    this.colorValue = `hsla(${hsl.h}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%,${_alpha / 100})`;
                    break;
                }
                case 'hsv': {
                    this.colorValue = `hsva(${_hue}, ${Math.round(_saturation)}%, ${Math.round(_value)}%,${_alpha / 100})`;
                    break;
                }
                default: {
                    const { r, g, b } = hsv2rgb(_hue, _saturation, _value);
                    this.colorValue = `rgba(${r}, ${g}, ${b},${_alpha / 100})`;
                    break;
                }
            }
        } else {
            switch (format) {
                case 'hsl': {
                    const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100);
                    this.colorValue = `hsl(${hsl.h}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
                    break;
                }
                case 'hsv': {
                    this.colorValue = `hsv(${_hue}, ${Math.round(_saturation)}%, ${Math.round(_value)}%)`;
                    break;
                }
                case 'rgb': {
                    const { r, g, b } = hsv2rgb(_hue, _saturation, _value);
                    this.colorValue = `rgb(${r}, ${g}, ${b})`;
                    break;
                }
                default:
                    this.colorValue = rgbtoHex(hsv2rgb(_hue, _saturation, _value));
            }
        }

    }

    //添加颜色点
    addgradientPoint(colorObj) {
        if (this.gradientDots > this._genGradientPoint.length) {
            this._genGradientPoint.push(colorObj);
            this._genGradientPoint.sort((a, b) => { return Number(a.position.replace("%", "")) - Number(b.position.replace("%", "")) })
            this.currentgenidChang(colorObj.genid)
        }
    }


    // 删除某个颜色点
    deletePoint(e) {
        let pIndex = this._genGradientPoint.findIndex((c) => c.genid === this.currentgenid);
        const { length } = this._genGradientPoint;
        // 必须保证有两个点
        if (['delete', 'backspace'].includes(e.key.toLocaleLowerCase()) && length > 2 && pIndex >= 0 && pIndex <= length - 1) {
            this._genGradientPoint.splice(pIndex, 1)
            if (!this._genGradientPoint[pIndex]) {
                pIndex = this._genGradientPoint[pIndex + 1] ? pIndex + 1 : this._genGradientPoint[pIndex - 1] ? pIndex - 1 : 0;
            }
            this.currentgenidChang(this._genGradientPoint[pIndex].genid)
        }
    }


    //某一节点的渐变色更新
    doChangeLineposition() {
        const index = this._genGradientPoint.findIndex((c) => c.genid === this.currentgenid);
        if (index === -1) {
            return;
        }
        const point = this._genGradientPoint[index];
        this._genGradientPoint.splice(index, 1, {
            color: this.colorValue,
            position: this._lineMove,
            genid: point.genid,
        });
        this._genGradientPoint.sort((a, b) => { return Number(a.position.replace("%", "")) - Number(b.position.replace("%", "")) })
        //生成渐变色
        this.handleColorsChange();
    }
    //设置节点的颜色在色板上显示
    currentgenidChang(id) {
        this.currentgenid = id;
        const index = this._genGradientPoint.findIndex((c) => c.genid === this.currentgenid);
        if (index === -1) {
            return;
        }
        const point = this._genGradientPoint[index];
        this._lineMove = point.position;
        //根据当前点选中的颜色去设置单色面板的颜色
        this.colorValue = point.color;
        this.setcurrentHSVA()
        this.handleColorsChange();
    }
    //设置当前颜色的H，S，V，A
    setcurrentHSVA() {
        const fromHSV = (h, s, v) => {
            this._hue = Math.max(0, Math.min(360, h));
            this._saturation = Math.max(0, Math.min(100, s));
            this._value = Math.max(0, Math.min(100, v));
        };

        if (this.colorValue.indexOf('hsl') !== -1) {
            const parts = this.colorValue.replace(/hsla|hsl|\(|\)/gm, '')
                .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));

            if (parts.length === 4) {
                this._alpha = Math.floor(parseFloat(parts[3]) * 100);
            } else if (parts.length === 3) {
                this._alpha = 100;
            }
            if (parts.length >= 3) {
                const { h, s, v } = hsl2hsv(parts[0], parts[1], parts[2]);
                fromHSV(h, s, v);
            }
        } else if (this.colorValue.indexOf('hsv') !== -1) {
            const parts = this.colorValue.replace(/hsva|hsv|\(|\)/gm, '')
                .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
            if (parts.length === 4) {//有透明度
                this._alpha = Math.floor(parseFloat(parts[3]) * 100);
            } else if (parts.length === 3) {
                this._alpha = 100;
            }
            if (parts.length >= 3) {
                fromHSV(parts[0], parts[1], parts[2]);
            }
        } else if (this.colorValue.indexOf('rgb') !== -1) {
            let parts = this.colorValue.replace(/rgba|rgb|\(|\)/gm, '')
                .split(/\s|,/g)
                .filter((val) => val !== '')
                .map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
            if (parts.length === 4) {//有透明度
                this._alpha = Math.floor(parseFloat(parts[3]) * 100);
            } else if (parts.length === 3) {//没有透明度
                this._alpha = 100;
            }
            if (parts.length >= 3) {
                const { h, s, v } = rgb2hsv(parts[0], parts[1], parts[2]);
                fromHSV(h, s, v);
            }
        } else if (value.indexOf('#') !== -1) {

        }
    }

    // 生成渐变色
    handleColorsChange() {
        let colorPoint = this._genGradientPoint.map((item) => item.color + ' ' + item.position);
        colorPoint = colorPoint.join();
        if (this._angle) {
            this.gradientcolorValue = `linear-gradient(${this._angle}deg,${colorPoint})`;
        } else {
            this.gradientcolorValue = `linear-gradient(${colorPoint})`;
        }
    }
}